package info.emamian.droplet.worker.sms;

import info.emamian.droplet.data.DynamoDbSms;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.ApplicationContext;

public class DrugInfoHandler extends AbstractSMSHandler {

	private static final String SPLIT_DELIMITER = "\t";

	private static final Logger LOGGER = LoggerFactory.getLogger(DrugInfoHandler.class);

	@Deprecated
	private static final String INPUTS_PREFIX = "inputs";

	private final Map<String, String> name2DescriptionMap = new HashMap<String, String>();

	public DrugInfoHandler(final File namesAndDescriptionsFile) throws IOException {
		// parseFromFile(applicationContext, "drugs.csv");
		loadNameAndDescriptionFromFile(namesAndDescriptionsFile);
	}

	@Override
	protected String processAnswer(final DynamoDbSms sms) {
		if (sms.getFirstWord().equalsIgnoreCase("drug")) {
			if (sms.getWords().size() < 2) { return getUsage(); }
			String drugName = sms.getBody().substring(sms.getFirstWord().length()).trim().toLowerCase();
			if (drugName == null || drugName.isEmpty()) { return getUsage(); }

			if (drugName != null && drugName.length() > 0 && name2DescriptionMap.containsKey(drugName)) {
				return name2DescriptionMap.get(drugName);
			} else {
				if (drugName.length() > 100) {
					drugName = drugName.substring(0, 100) + "...";
				}
				return "No drug information found for: " + drugName;
			}
		}
		return null;
	}

	@Override
	public String getUsage() {
		return "drug [drug name]";
	}

	private void loadNameAndDescriptionFromFile(final File file) throws IOException {
		long start_time = System.currentTimeMillis();
		if (file == null) {
			LOGGER.error("input file cannot be null {}", file);
			return;
		}
		LOGGER.info("Loading drug names and descriptions from file:{}", file.getPath());
		// FileSystemResource fsr = new FileSystemResource(filePath);
		// BufferedReader br = new BufferedReader(new
		// FileReader(fsr.getFile()));
		BufferedReader br = new BufferedReader(new FileReader(file));
		String line;
		int count = 0;
		while ((line = br.readLine()) != null) {
			line = line.trim();
			if (line.isEmpty()) {
				continue;
			}
			String[] parts = line.split(SPLIT_DELIMITER);
			if (parts.length < 2) {
				continue;
			}

			String name = parts[0].trim().toLowerCase();
			String desciption = parts[1].trim();
			if (name2DescriptionMap.containsKey(name)) {
				// already added
				// TODO
			} else {
				name2DescriptionMap.put(name, desciption);
				count++;
			}
		}
		br.close();
		LOGGER.info(String.format("Finished loading, took %s ms loading %s drug names and description from file:%s", (System.currentTimeMillis() - start_time), count,
				file.getPath()));
	}

	@SuppressWarnings("unused")
	@Deprecated
	private void parseFromFile(final ApplicationContext applicationContext, final String filename) throws IOException {
		// ServletContextResource resource = new
		// ServletContextResource(servletContext, filename);
		// BufferedReader br = new BufferedReader(new
		// InputStreamReader(servletContext.getResourceAsStream(filename)));
		BufferedReader br = new BufferedReader(new FileReader(applicationContext.getResource(INPUTS_PREFIX + "/" + filename).getFile()));
		LOGGER.info("reading file" + new Date());
		String line;
		String nl = "null".intern();
		int emptyLine = 0;
		int malfrmed = 0;
		int keyEmpty = 0;
		int valEmpty = 0;
		int valNull = 0;
		int bigVal = 0;
		int dotError = 0;
		int commaError = 0;
		int spaceError = 0;
		HashMap<Integer, Integer> sizes = new HashMap<Integer, Integer>();
		while ((line = br.readLine()) != null) {
			line = line.trim();
			if (line.isEmpty()) {
				emptyLine++;
				continue;
			}
			String[] str = line.split("\",\"");
			if (str.length < 3) {
				malfrmed++;
				continue;
			}
			if (str[0].length() < 2) {
				keyEmpty++;
				continue;
			}
			if (str[2].length() < 2) {
				valEmpty++;
				continue;
			}
			String key = str[0].substring(1).trim();
			String val = str[2].substring(0, str[2].length() - 1).trim();
			if (key.isEmpty()) {
				keyEmpty++;
				continue;
			}
			if (val.isEmpty()) {
				valEmpty++;
				continue;
			}
			if (val.equalsIgnoreCase(nl)) {
				valNull++;
				continue;
			}
			if (val.length() > 160) {
				bigVal++;
				int idx = val.lastIndexOf(".", 160);
				if (idx != -1) {
					LOGGER.info("idx . " + idx + " : " + val.substring(0, idx));
					val = val.substring(0, idx);
				} else {
					dotError++;
					idx = val.lastIndexOf(",", 157);
					if (idx != -1) {
						System.err.println("idx2 , " + idx + " : " + val.substring(0, idx));
						val = val.substring(0, idx) + "...";
					} else {
						commaError++;
						idx = val.lastIndexOf(" ", 157);
						if (idx != -1) {
							System.err.println("KIDDING space " + idx + " : " + val.substring(0, idx));
							val = val.substring(0, idx) + "...";
						} else {
							spaceError++;
							System.err.println("RUN FOREST : " + val);
						}
					}
				}

			}
			name2DescriptionMap.put(key.toLowerCase(), val);
			if (!sizes.containsKey(val.length())) {
				sizes.put(val.length(), 1);
			} else {
				sizes.put(val.length(), sizes.get(val.length()) + 1);
			}
		}
		br.close();
		LOGGER.info("Emtpy Line :" + emptyLine);
		LOGGER.info("malformed :" + malfrmed);
		LOGGER.info("key empty :" + keyEmpty);
		LOGGER.info("val empty :" + valEmpty);
		LOGGER.info("val null :" + valNull);
		LOGGER.info("big :" + bigVal);
		LOGGER.info("err :" + dotError);
		LOGGER.info("zlen :" + commaError);
		LOGGER.info("try3 :" + spaceError);
		LOGGER.info(sizes.toString());
	}

	@Override
	protected List<String> getKewordsList() {
		String[] keywords = { "drug", "drg", "drugs" };
		return Arrays.asList(keywords);
	}
}
